#ifndef MU_RETURN_H
#define MU_RETURN_H


#include <iostream>
#include <vector>
#include "src/define/data_define.h"
#include "MU_ExpMessage.h"
#include <atomic>
#include <mutex>
#include <boost/signals2.hpp>

/// 函数执行状态
typedef enum MU_RETURN_LIST{
            MU_RETURN_SUCCESS            = 0,            ///< 成功
            MU_RETURN_ERROR              = -2001,        ///< 失败
            MU_RETURN_NO_DATA            = -2002,        ///< 没有数据
            MU_RETURN_INVALID_HANDLE     = -2003,        ///< 非法句柄
            MU_RETURN_INVALID_PARAMETER  = -2004,        ///< 参数非法
            MU_RETURN_OUT_RANGE          = -2005,        ///< 越界错误
            MU_RETURN_RUNTIME_ERROR      = -2006,        ///< 运行时错误
            MU_RETURN_LOGIC_ERROR        = -2007,        ///< 逻辑错误
            MU_RETURN_TIMEOUT_ERROR      = -2008,        ///< 超时错误
            MU_RETURN_DYNAMIC_CAST_ERROR = -2009,        ///< 动态类型转换错误
}MU_RETURNS;


/// 输出返回信息
inline std::string MU_Get_Msg(MU_RETURNS msg)
{
    std::string ret = "";
    switch (msg) {
    case MU_RETURN_SUCCESS:
        ret =  "没有异常发生!";
        break;
    case MU_RETURN_ERROR:
        ret =  "执行失败!";
        break;
    case MU_RETURN_NO_DATA:
        ret =  "没有数据!";
        break;
    case MU_RETURN_INVALID_HANDLE:
        ret =  "句柄无效!";
        break;
    case MU_RETURN_INVALID_PARAMETER:
        ret =  "非法参数!";
        break;
    case MU_RETURN_OUT_RANGE:
        ret =  "越界!";
        break;
    case MU_RETURN_LOGIC_ERROR:
        ret =  "逻辑错误!";
        break;
    case MU_RETURN_TIMEOUT_ERROR:
        ret =  "执行超时!";
        break;
    case MU_RETURN_DYNAMIC_CAST_ERROR:
        ret =  "类型转换错误!";
        break;
    default:
        ret =  "未定义的异常!";
        break;
    }
    return  ret;
}

/// 枚举异常表
typedef enum MU_ERROR_LIST{
    MU_ERROR_NO                         = 0,            ///< 成功
    MU_ERROR_MODULE_LOG                 = -100,        ///< 日志模块
    MU_ERROR_MODULE_IO                  = -101,        ///< 文件IO
    MU_ERROR_MODULE_CALC                = -102,        ///< 拟合计算
    MU_ERROR_MODULE_IMAGE               = -103,        ///< 图像算法出现异常
    MU_ERROR_MODULE_SQL                 = -104,        ///< 数据库
    MU_ERROR_MODULE_RESULT              = -105,        ///< 结果不符合预期造成的错误
    MU_ERROR_MODULE_CAM                 = -1001,        ///< 相机模块异常
    MU_ERROR_MODULE_LASER               = -1002,        ///< 激光
    MU_ERROR_MODULE_MACHINE             = -1003,        ///< 变位机
    MU_ERROR_MODULE_ROBOT               = -1004,        ///< 机器人
    MU_ERROR_MODULE_OHTERWISE           = -1005,        ///< 不可预知的
    MU_ERROR_MODULE_WELD                = -1006,        ///< 焊接
    MU_ERROR_MODULE_COMMUNICATE         = -1007,        ///< 通信
    MU_ERROR_MODULE_PLC                 = -1008,        ///< plc
    MU_ERROR_MODULE_APP                 = -1009,        ///< 由内部程序出现的异常造成的崩溃


}MU_E_TYPE;





/// 任务索引
typedef enum MU_TASK_LIST{
            MU_TASK_INDEX_NONE      = 0b00,
            MU_TASK_INDEX_CAM       = 0x1 << 0,
            MU_TASK_INDEX_PLC       = 0x1 << 1,
            MU_TASK_INDEX_WELD      = 0x1 << 2,
            MU_TASK_INDEX_LOG       = 0x1 << 3,
            MU_TASK_INDEX_SQL       = 0x1 << 4,
            MU_TASK_INDEX_IO        = 0x1 << 5,
            MU_TASK_INDEX_MACHINE   = 0x1 << 6,
            MU_TASK_INDEX_LASYER    = 0x1 << 7,
            MU_TASK_INDEX_CALC      = 0x1 << 8,
            MU_TASK_INDEX_IMAGE     = 0x1 << 9,
            MU_TASK_INDEX_ROBOT     = 0x1 << 10,
}MU_TASK_INDEX;

/// 设备初始化用的索引
typedef enum MU_DEVICE_INDEX{
    MU_DEVICE_NONE = 0,     /// 预留
    MU_DEVICE_CAM,          /// 相机 1
    MU_DEVICE_PLC,          /// PLC 2
    MU_DEVICE_WELD,         /// 焊丝 3
    MU_DEVICE_LOG,          /// 日志系统 4
    MU_DEVICE_SQL,          /// 数据库 5
    MU_DEVICE_IO,           /// 预留
    MU_DEVICE_MACHINE,      /// 变位机
    MU_DEVICE_LASYER,       /// 激光
    MU_DEVICE_CALC,         /// 预留
    MU_DEVICE_IMAGE,        /// 图像算法加载器
    MU_DEVICE_ROBOT,         /// 机器人
    MU_DEVICE_ALL
}MU_DEVICE_I;

static MU_DEVICE_I & operator++(MU_DEVICE_I &ts ){
    int e = ts;
    ts = (enum MU_DEVICE_INDEX)(e +1);
    return ts;
}


/// 系统运行状态表
typedef enum MU_STATUS_LIST{
            MU_STATUS_NOTRUN             = 0,            ///< 程序当前没有设备运行
            MU_STATUS_SUCCESS            = 1,            ///< 程序当前处于正常模式
            MU_STATUS_PAUSE              = -1001,        ///< 程序当前处于暂停模式
            MU_STATUS_CRASH              = -1002,        ///< 程序处于异常状态且不可预知
}MU_S_LIST;

/**
 * @brief Error_Msg
 * @param
 * 0:描述   1.枚举的错误类型    2.产生异常的时间
 */
typedef  std::tuple<std::string,MU_E_TYPE,std::string> Error_Msg;   // 定义每次的异常及备注信息


typedef enum  MU_INIT_STSTUS{
    MU_TY_TRUE          = 2 ,      /// 初始化成功
    MU_TY_FALSE         = -1,       /// 失败
    MU_TY_RUNNING       = 0 ,     /// 正在
    MU_TY_NONE          = 1,       /// 没有进行初始化
    MU_TY_STOP          = -3,       /// 失败
}MU_INIT_TYPE;

#define TIME_OUT_S 20    /// 定义通用超时时间  s

typedef  std::pair<MU_INIT_TYPE ,bool> DEVICE_INIT;            /// 存储设备初始化时的状态0:Init状态  1:初始化的结果
typedef  std::map<MU_DEVICE_I,DEVICE_INIT> DEVICE_MAP;

/// 当前系统状态
typedef struct MU_APP_INFO{
            std::string curVer;                                              /// 当前版本
            std::atomic<MU_STATUS_LIST> status = {MU_STATUS_NOTRUN};         /// 当前运行状态
            std::atomic<UC2> run_Process = ATOMIC_FLAG_INIT;                 /// 任务状态表，0:非暂停态  1：暂停态
            std::deque<Error_Msg> error;                                     /// 当前的异常信息集合
            std::deque<Error_Msg> warning;                                   /// 当前的警告信息集合
            DEVICE_MAP device;                                  /// 存储硬件初始化结果表 first:索引   second:result
            std::atomic<int> expLock = ATOMIC_FLAG_INIT;        /// 异常优先级调度
            std::mutex g_mtx;                                   /// 锁对象
            std::atomic<bool> flag =  ATOMIC_FLAG_INIT;         /// 暂时未使用
            std::recursive_mutex _mtx ;

            boost::signals2::signal<void (MU_DEVICE_I)> deviceChanged ;    // 模块上下线检测

            /**
             * @brief operator <<
             * @param msg
             * @details 推送异常消息事件
             */
            void operator <<(Error_Msg msg){
                std::lock_guard<std::recursive_mutex> lck(_mtx) ;
                error.push_back(msg);
            }

            /**
             * @brief operator <<
             * @param msg
             * @details 推送警告消息事件
             */
            void operator <(Error_Msg msg){
                std::lock_guard<std::recursive_mutex> lck(_mtx) ;
                warning.push_back(msg);
            }

            // 获取初始化结果
            bool GetInit(MU_DEVICE_I index){
                std::lock_guard<std::recursive_mutex> lck(_mtx) ;
                return device[index].second;
            }

            MU_INIT_TYPE GetInitType(MU_DEVICE_I index){
                std::lock_guard<std::recursive_mutex> lck(_mtx) ;
                return device[index].first;
            }

            void setInitType(MU_DEVICE_I index,MU_INIT_TYPE status){
                std::unique_lock<std::mutex> lg(g_mtx,std::defer_lock);
                if(lg.try_lock()){
                    device[index].first = status;
                    flag.exchange(true);
                }
                lg.unlock();
            }

            void initSucess(MU_DEVICE_I index){
                std::unique_lock<std::mutex> lg(g_mtx,std::defer_lock);
                if(lg.try_lock()){
                    device[index].first = MU_TY_TRUE;
                    device[index].second = true;
                    flag.exchange(true);
                    deviceChanged(index);
                }
                lg.unlock();
                std::cout << BOLDGREEN << "Init Sucess:"<<MU_Messages::Module[index]<<"\t"<<index<<"\t"<< device[index].second<<RESET<<std::endl;
            }

            void initFailed(MU_DEVICE_I index){
                std::unique_lock<std::mutex> lg(g_mtx,std::defer_lock);
                if(lg.try_lock()){
                    device[index].first = MU_TY_FALSE;
                    device[index].second = false;
                    flag.exchange(true);
                    deviceChanged(index);
                }
                lg.unlock();
            }
            void SetStop(MU_DEVICE_I index){
                std::unique_lock<std::mutex> lg(g_mtx,std::defer_lock);
                if(lg.try_lock()){
                    device[index].first = MU_TY_STOP;
                    device[index].second = false;
                    flag.exchange(true);
                }
                lg.unlock();
            }
            void initDefaultAll(){
                std::unique_lock<std::mutex> lg(g_mtx,std::defer_lock);
                if(lg.try_lock()){
                    for(int i = 0;i<MU_DEVICE_ALL;i++){
                        auto t = std::make_pair(MU_DEVICE_I(i),std::make_pair(MU_TY_NONE,false));
                        device.insert(t);
                        flag.exchange(true);
                    }
                    std::cout << "end Default!"<<std::endl;
                }
                lg.unlock();
            }


}MU_A_INFO;


/// 输出异常代码信息
inline std::string MU_Get_Msg(MU_E_TYPE &msg)
{
    std::string ret = "";
    switch (msg) {
    case MU_ERROR_NO:
        ret =  "没有异常发生!";
        break;
    case MU_ERROR_MODULE_CAM:
        ret =  "相机异常!";
        break;
    case MU_ERROR_MODULE_IO:
        ret =  "文件IO异常!";
        break;
    case MU_ERROR_MODULE_APP:
        ret =  "应用异常!";
        break;
    case MU_ERROR_MODULE_LOG:
        ret =  "日志系统异常!";
        break;
    case MU_ERROR_MODULE_PLC:
        ret =  "PLC系统异常!";
        break;
    default:
        ret =  "未定义的异常!";
        break;
    }
    return  ret;
}


extern MU_A_INFO currentStatus;    /// 当前系统状态

/**
 * @brief pushExp
 * @param e 异常类型
 * @param time  时间
 */
static void pushExp(std::vector<std::string> desc,int errorCode,MU_E_TYPE e,std::string time){
    currentStatus << std::make_tuple(GetErrString(desc,errorCode),e,time);
}

static void pushExp(std::vector<std::string> desc,int errorCode,MU_E_TYPE e){
    time_t t = time(NULL);
    char ch[64] = {0};
    strftime(ch, sizeof(ch) - 1, "%Y-%m-%d %H:%M:%S", localtime(&t));     //年-月-日 时-分-秒
    currentStatus << std::make_tuple(GetErrString(desc,errorCode),e,ch);
}

/**
 * @brief pushWarn
 * @param desc      描述容器
 * @param errorCode 描述码的索引
 * @param e 故障类型
 * @details 推送一个警告消息
 */
static void pushWarn(std::vector<std::string> desc,int errorCode,MU_E_TYPE e){
    time_t t = time(NULL);
    char ch[64] = {0};
    strftime(ch, sizeof(ch) - 1, "%Y-%m-%d %H:%M:%S", localtime(&t));     //年-月-日 时-分-秒
    currentStatus < std::make_tuple(GetErrString(desc,errorCode),e,ch);
}

/**
 * @brief pushWarn
 * @param str      描述
 * @param e 故障类型
 * @details 推送一个警告消息
 */
static void pushWarn(std::string str,MU_E_TYPE e){
    time_t t = time(NULL);
    char ch[64] = {0};
    strftime(ch, sizeof(ch) - 1, "%Y-%m-%d %H:%M:%S", localtime(&t));     //年-月-日 时-分-秒
    currentStatus < std::make_tuple(str,e,ch);
}


static bool getSystemStatus(){
    return MU_STATUS_SUCCESS == currentStatus.status.load(std::memory_order_relaxed);
}


#endif // MU_RETURN_H
